package br.org.isvi.interpretador.portugol.types;

public abstract class SymbolImpl implements Symbol {

	private Kind kind;
	private Object value;

	public SymbolImpl(Kind kind, Object value) {
		this.kind = kind;
		this.value = value;
	}

	public Kind getKind() {
		return kind;
	}

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		// SOMENTE VARIAVEIS PODEM TER SEUS VALORES ALTERADOS
		if (kind.equals(Kind.VARIAVEL)) {			
			if (value instanceof Variable) {
				Object tvalue = ((Variable) value).getValue();
				
				if(tvalue != null) {
					value = tvalue;
				}
				
			} else {
				
				if(value != null) {					
					this.value = value;
				}
			}
		}
	}
	
	public boolean compatible(Symbol symb) {
		return getRealValue(symb).getKind() == getRealValue(this).getKind();
	}
	
	/**
	 * Retorna o valor real, no caso de variaveis o valor interno.
	 * 
	 * @param entry
	 * @return
	 */
	public Symbol getRealValue(Symbol entry) {
		Symbol ret = entry;
		
		if(entry.getKind() == Kind.VARIAVEL) {
			ret = (Symbol)entry.getValue();
		}
		
		return ret;
	}
}
